package com.echat.serviceapigateway.security.excepetion;

import com.echat.commonlib.constant.ErrorCode;
import com.echat.commonlib.exception.exc.base.EchatException;
import com.echat.serviceapigateway.security.common.HttpResult;
import com.netflix.client.ClientException;
import com.netflix.zuul.http.HttpServletRequestWrapper;
import org.eclipse.jetty.server.Request;
import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

/**
 * Created by chenmohan on 2018/09/03
 *
 * @description 异常处理controller,全局异常处理器捕获到异常后会将请求转发到此controller上
 */
@RestController
public class JsonErrorController extends AbstractErrorController {

    public JsonErrorController(ErrorAttributes errorAttributes) {
        super(errorAttributes);
    }

    @RequestMapping(value = "/errorWithJson", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public HttpResult errorWithJson(HttpServletRequest request, Integer code, String msg) {
        //     String s = request.getRequestURI();
        if(code == null || msg == null){
            ServletRequest rawRequest = getRawRequest(request);
            code = Integer.valueOf(rawRequest.getParameter("code"));
            msg = rawRequest.getParameter("msg");
        }
        return HttpResult.error(code, msg);
    }

    @RequestMapping("/interceptorExcpetion")
    public void interceptorExcpetion(HttpServletRequest request) throws Throwable {
        Throwable exception = (Throwable) request.getAttribute("exception");
        throw exception;
    }

    /**
     * 设置Springboot默认的错误页面地址
     *
     * @return
     */
    @Override
    public String getErrorPath() {
        return "/error";
    }

    @RequestMapping(value = "/error", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public HttpResult error(HttpServletRequest request) throws NoHandlerFoundException {
        //先看是不是404异常
        HttpStatus status = getStatus(request);
        if (status.value() == 404) {
            throw new NoHandlerFoundException(request.getMethod(), ((Request) request).getOriginalURI(), null);
        }
        //网关调用相应服务发生的异常
        Object attribute = request.getAttribute("javax.servlet.error.exception");
        if (attribute == null) {
            return HttpResult.error(500, "有点小问题");
        }
        Throwable cause = ((Exception) attribute).getCause();
        if (cause instanceof EchatException) {
            EchatException exception = (EchatException) cause;
            return HttpResult.error(exception.getCode(), exception.getMessage());
        } else if (cause instanceof ClientException) {
            return HttpResult.error(ErrorCode.SERVER_ERROR, "网关服务正在构建中，请稍后");
        }
        return HttpResult.error(500, cause.getMessage() == null ? "未知异常[" + cause + "]" : cause.getMessage());
    }

    private ServletRequest getRawRequest(HttpServletRequest request){
        HttpServletRequest servletRequest = ((HttpServletRequestWrapper) request).getRequest();
        javax.servlet.http.HttpServletRequestWrapper httpServletRequestWrapper = (javax.servlet.http.HttpServletRequestWrapper)servletRequest;
        ServletRequest rawRequest = httpServletRequestWrapper.getRequest();
        return rawRequest;
    }

}
